//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
/******************************************************************************
**
**  COPYRIGHT (C) 2000, 2002 Intel Corporation.
**
**  This software as well as the software described in it is furnished under 
**  license and may only be used or copied in accordance with the terms of the 
**  license. The information in this file is furnished for informational use 
**  only, is subject to change without notice, and should not be construed as 
**  a commitment by Intel Corporation. Intel Corporation assumes no 
**  responsibility or liability for any errors or inaccuracies that may appear 
**  in this document or any software that may be provided in association with 
**  this document. 
**  Except as permitted by such license, no part of this document may be 
**  reproduced, stored in a retrieval system, or transmitted in any form or by 
**  any means without the express written consent of Intel Corporation. 
**
**  FILENAME:       xllp_msl.h
**
**  PURPOSE:        This is the main header file for XLLP primitives for the 
**     Mobile Scalable Link (MSL) bus.
**
******************************************************************************/

#ifndef _xllp_msl_h_
#define _xllp_msl_h_

//
// HEADER FILES
//
#include "xllp_defs.h"

//
// Register addresses
//
#define BASE_ADDRESS_FIFO_REGISTERS  (BASE_ADDRESS_MSL_REGISTERS + CHANNEL_FIFO_REGISTER_OFFSET)
#define BASE_ADDRESS_CONFIG_REGISTERS (BASE_ADDRESS_MSL_REGISTERS + CHANNEL_CONFIG_REGISTER_OFFSET)
#define BASE_ADDRESS_STATUS_REGISTERS (BASE_ADDRESS_MSL_REGISTERS + CHANNEL_STATUS_REGISTER_OFFSET)
#define BASE_ADDRESS_EOM_REGISTERS  (BASE_ADDRESS_MSL_REGISTERS + CHANNEL_EOM_REGISTER_OFFSET)
#define BASE_ADDRESS_CONTROL_REGISTERS (BASE_ADDRESS_MSL_REGISTERS + CHANNEL_CONTROL_REGISTER_OFFSET)

//
// Number of logical data channels in each of outbound and inbound links
// for defining MSL register map
// This should probably remain constant across all hardware ASICS (Bulverde, Manitoba, etc.)
// that use MSL.
// MSL registers for a particular channel are likely to be at the same address location across
// all ASICS
//
#define MSL_NUM_CHANNEL_ADDRESSES  7

//
// Offset in between the addresses of the MSL FIFO register
//
#define MSL_FIFO_OFFSET                 4

//
// Channel Receive/Transmit FIFO register
//
typedef struct
{
    XLLP_VUINT32_T BBFIFO[MSL_NUM_CHANNEL_ADDRESSES];

} XllpFifoRegT, *P_XllpFifoRegT;

//
// Channel configuration register
//
typedef struct
{
    XLLP_VUINT32_T BBCFG[MSL_NUM_CHANNEL_ADDRESSES];

} XllpConfigRegT, *P_XllpConfigRegT;

//
// Channel status register
//
typedef struct
{
    XLLP_VUINT32_T BBSTAT[MSL_NUM_CHANNEL_ADDRESSES];

} XllpStatusRegT, *P_XllpStatusRegT;

//
// Channel EOM register
//
typedef struct
{
    XLLP_VUINT32_T BBEOM[MSL_NUM_CHANNEL_ADDRESSES];

} XllpEomRegT, *P_XllpEomRegT;

typedef struct
{
    XLLP_VUINT32_T BBCSTP;  // Channel Stop Threshold Register
    XLLP_VUINT32_T BBCSTR;  // Channel Start Threshold Register
    XLLP_VUINT32_T BBIID;   // Standard Interface Interrupt ID Register
    XLLP_UINT32_T Reserved1;
    XLLP_VUINT32_T BBFREQ;  // Transmit frequency Select Register
    XLLP_VUINT32_T BBWAIT;  // Wait Count Register
    XLLP_VUINT32_T BBCST;   // Clock Stop Time Register
    XLLP_VUINT32_T BBVGIL;  // Virtual GPIO Input Pin Level Register
    XLLP_VUINT32_T BBVGOL;  // Virtual GPIO Output Pin Level Register
    XLLP_VUINT32_T BBVGSR;  // Virtual GPIO Output Pin Set Register
    XLLP_VUINT32_T BBVGCR;  // Virtual GPIO Output Pin Clear Register
    XLLP_VUINT32_T BBVGRE;  // Virtual GPIO Rising Edge Detect Register
    XLLP_VUINT32_T BBVGFE;  // Virtual GPIO Falling Edge Detect Register
    XLLP_VUINT32_T BBVGED;  // Virtual GPIO Edge Detect Status Register
    XLLP_VUINT32_T BBVGVI;  // Virtual GPIO Value Interrupt Register
    XLLP_UINT32_T Reserved2;
    XLLP_VUINT32_T BBWAKE;  // Wake up Register
    XLLP_VUINT32_T BBITFC;  // Interface width register

} XllpControlRegT, *P_XllpControlRegT;

typedef struct
{
    XLLP_UINT32_T         Reserved1;
    XllpFifoRegT          FifoReg;      // Fifo Registers
    XLLP_UINT32_T         Reserved2[9];
    XllpConfigRegT        ConfigReg;    // Config Registers
    XLLP_UINT32_T         Reserved3[9];
    XllpStatusRegT        StatusReg;    // Status Registers
    XLLP_UINT32_T         Reserved4[9];
    XllpEomRegT           EomReg;       // EOM Registers
    XLLP_UINT32_T         Reserved5[8];
    XllpControlRegT       ControlReg;   // Control Registers

} XllpMslRegT, *P_XllpMslRegT;

//
// Register Bit fields
//

//
// Channel Configuration Register (BBCFG) bitfields
//
#define XLLP_MSL_BBCFG_TxEnable      (0)  // Transmit FIFO Channel Enable
#define XLLP_MSL_BBCFG_TxMFCEnable   (1)  // Transmit Message Flow Control Enable
#define XLLP_MSL_BBCFG_TxDFCEnable   (2)  // Transmit Direct Flow Control Enable
#define XLLP_MSL_BBCFG_TxThreshLevel (3)  // Transmit FIFO Service Threshold
#define XLLP_MSL_BBCFG_TxService     (5)  // Transmit FIFO Service Select
#define XLLP_MSL_BBCFG_TxBlock       (8)  // Transmit Block Size
#define XLLP_MSL_BBCFG_RxEnable      (16) // Receive FIFO Channel Enable
#define XLLP_MSL_BBCFG_RxMFCEnable   (17) // Receive Message Flow Control Enable
#define XLLP_MSL_BBCFG_RxDFCEnable   (18) // Receive Direct Flow Control Enable
#define XLLP_MSL_BBCFG_RxThreshLevel (19) // Receive FIFO Service Threshold
#define XLLP_MSL_BBCFG_RxService     (21) // Receive FIFO Service Select
#define XLLP_MSL_BBCFG_EOCService    (24) // Early EOC Service Select

//
// Channel Status Register (BBCFG) bitfields
//
#define XLLP_MSL_BBSTAT_TxFullness  (0x1U << 0)  // Fullness of Transmit FIFO
#define XLLP_MSL_BBSTAT_TxFull      (0x1U << 6)  // Transmit FIFO full
#define XLLP_MSL_BBSTAT_TxEmpty     (0x1U << 7)  // Transmit FIFO Empty
#define XLLP_MSL_BBSTAT_TxWait      (0x1U << 8)  // Transmit channel in WAIT state
#define XLLP_MSL_BBSTAT_RxFullness  (0x1U << 16) // Fullness of Receive FIFO
#define XLLP_MSL_BBSTAT_RxFull      (0x1U << 22) // Receive FIFO full
#define XLLP_MSL_BBSTAT_RxEmpty     (0x1U << 23) // Receive FIFO Empty
#define XLLP_MSL_BBSTAT_RxWait      (0x1U << 24) // Receive channel in WAIT state
#define XLLP_MSL_BBSTAT_RxEomFifo   (0x1U << 25) // Receive channel received EOM
#define XLLP_MSL_BBSTAT_RxEom_1     (0x1U << 28) // Next byte to be read from FIFO is last byte in msg
#define XLLP_MSL_BBSTAT_RxEom_2     (0x1U << 29) // Second byte to be read from FIFO is last byte in msg
#define XLLP_MSL_BBSTAT_RxEom_3     (0x1U << 30) // Third byte to be read from FIFO is last byte in msg
#define XLLP_MSL_BBSTAT_RxEom_4     (0x1U << 31) // Fourth byte to be read from FIFO is last byte in msg

//
// Standard interface interrupt (BBIID) Register bitfields
//
#define XLLP_MSL_BBIID_VGPIO_INT    (0x1U << 0)   // VGPIO Interrupt
#define XLLP_MSL_BBIID_RX_INT(ch)   (0x1U << (1+ch)) // Receive FIFO interrupt for channel (0<=ch<7)
#define XLLP_MSL_BBIID_EOC_INT(ch)  (0x1U << (9+ch)) // EOC interrupt for channel (ch)
#define XLLP_MSL_BBIID_TX_INT(ch)   (0x1U << (17+ch)) // Transmit FIFO interrupt for channel (ch)

//
// Transmit Frequency Select (BBFRQ) Register bitfields
//
#define XLLP_MSL_BBFREQ_DIV    (4)   // BB_INT Clock divider

//
// Interface Width (BBITFC) Register bitfields
//
#define XLLP_MSL_BBITFC_TXITFC   (00)   // Transmit (outbound) link interface width
#define XLLP_MSL_BBITFC_RXITFC   (16)   // Receive  (inbound)  link interface width

#define XLLP_MSL_MAX_RX_FIFO            64              // Max number of words in RX FIFO
#define XLLP_MSL_MAX_TX_FIFO            64              // Max number of words in TX FIFO

#define XLLP_MSL_MAX_VGPIO_PINS         32              // Max number of VGPIO pins
//================================================================================

typedef enum
{
    XLLP_FIFO_CHANNEL_DISABLE=0,
    XLLP_FIFO_CHANNEL_ENABLE

} XllpMslChannelEnableTypeT;

typedef enum
{
    XLLP_MFC_DISABLE = 0,
    XLLP_MFC_ENABLE

} XllpMslMfcEnableTypeT;

typedef enum
{
    XLLP_DFC_DISABLE = 0,
    XLLP_DFC_ENABLE

} XllpMslDfcEnableTypeT;

typedef enum
{
    XLLP_FIFO_SERVICE_THRESHOLD_4_BYTES = 0 ,
    XLLP_FIFO_SERVICE_THRESHOLD_8_BYTES  ,
    XLLP_FIFO_SERVICE_THRESHOLD_16_BYTES ,
    XLLP_FIFO_SERVICE_THRESHOLD_32_BYTES

} XllpMslFifoSvcThreshTypeT;

typedef enum
{
    XLLP_FIFO_SERVICE_NONE = 0,
    XLLP_FIFO_SERVICE_DMA,
    XLLP_FIFO_SERVICE_INTERRUPT

} XllpMslFifoServiceTypeT;

typedef enum
{
    XLLP_EOC_SERVICE_NONE = 0,
    XLLP_EOC_SERVICE_INTERRUPT

} XllpMslEocServiceTypeT;

typedef enum
{
    XLLP_TX_BLOCK_4_BYTES = 0 ,
    XLLP_TX_BLOCK_8_BYTES     ,
    XLLP_TX_BLOCK_16_BYTES    ,
    XLLP_TX_BLOCK_32_BYTES

} XllpMslTxBlockTypeT;

typedef enum
{
    XLLP_INTERFACE_WIDTH_1_BIT = 0,
    XLLP_INTERFACE_WIDTH_2_BIT,
    XLLP_INTERFACE_WIDTH_4_BIT

} XllpMslInterfaceWidthTypeT;

typedef enum
{
    InputVgpioPin = 0,
    OutputVgpioPin

} XllpVgpioPinTypeT;

typedef enum
{
    VgpioNone = 0,
    VgpioRisingEdge,
    VgpioFallingEdge,
    VgpioRisingAndFallingEdge
} XllpMslVgpioEdgeTypeT;

//
// FUNCTION PROTOTYPES
//
void XllpMslConfigureBus(P_XllpMslRegT       pMslRegBase,
                XLLP_UINT32_T                maxNumChannels,
                XllpMslInterfaceWidthTypeT   interfaceWidth,
                XLLP_UINT32_T                xmitFreqDivisor,
                XLLP_UINT32_T                clockStopTime,
                XLLP_UINT32_T                mfcStopThreshold,
                XLLP_UINT32_T                mfcStartThreshold,
                XLLP_UINT32_T                waitTime);

void XllpMslConfigureRxChannel( P_XllpMslRegT    pMslRegBase,
                XLLP_INT32_T                     channel,
                XllpMslChannelEnableTypeT rxChannelEnable,
                XllpMslMfcEnableTypeT  rxMfcEnable,
                XllpMslDfcEnableTypeT  rxDfcEnable,
                XllpMslFifoSvcThreshTypeT fifoSvcThreshold,
                XllpMslFifoServiceTypeT  fifoServiceType,
                XllpMslEocServiceTypeT  eocServiceType);

void XllpMslConfigureTxChannel(P_XllpMslRegT    pMslRegBase,
                XLLP_INT32_T     channel,
                XllpMslChannelEnableTypeT txChannelEnable,
                XllpMslMfcEnableTypeT  txMfcEnable,
                XllpMslDfcEnableTypeT  txDfcEnable,
                XllpMslFifoSvcThreshTypeT fifoSvcThreshold,
                XllpMslFifoServiceTypeT  fifoServiceType);

void XllpMslSetTxFifoService    (P_XllpMslRegT    pMslRegBase,
                XLLP_INT32_T    channel,
                XLLP_UINT32_T               bEnable);

void XllpMslSetRxFifoService    (P_XllpMslRegT    pMslRegBase,
                XLLP_INT32_T    channel,
                XLLP_UINT32_T               bEnable);

void XllpMslDisableTxFifoService(P_XllpMslRegT    pMslRegBase,
                XLLP_INT32_T    channel);

void XllpMslEmptyRxFifo       (P_XllpMslRegT    pMslRegBase,
                XLLP_INT32_T        channel);

void XllpMslGetChannelStatus  ( P_XllpMslRegT    pMslRegBase,
                XLLP_INT32_T    channel,
                XLLP_UINT32_T    *status);

void XllpMslGetInterruptStatus(P_XllpMslRegT    pMslRegBase,
                XLLP_UINT32_T    *interruptStatus);
void XllpMslClearInterrupts   (P_XllpMslRegT    pMslRegBase,
                XLLP_UINT32_T    interruptMask);

void XllpMslSendWake     (P_XllpMslRegT    pMslRegBase );
void XllpMslSendEOM      (P_XllpMslRegT    pMslRegBase,
                XLLP_UINT32_T    channel);

XLLP_LEVEL_T XllpMslGetVgpioLevel    (P_XllpMslRegT    pMslRegBase,
                XllpVgpioPinTypeT   pinType,
                XLLP_UINT32_T    pinNumber);

void XllpMslSetVgpioLevel    (P_XllpMslRegT    pMslRegBase,
                XLLP_UINT32_T    pinNumber,
                XLLP_LEVEL_T    pinLevel);

void XllpMslConfigureVgpioEdgeDetect(P_XllpMslRegT   pMslRegBase,
                XLLP_UINT32_T   outputPinNumber,
                XllpMslVgpioEdgeTypeT pinEdgeType);

XLLP_BOOL_T XllpMslGetVgpioEdgeStatus (P_XllpMslRegT  pMslRegBase,
                XLLP_UINT32_T    inputPinNumber);

void XllpMslConfigureVgpioInterrupt(P_XllpMslRegT   pMslRegBase,
                XLLP_CONTROL_T   offOrOn);

__inline void XllpMslByteWrite(
                P_XllpMslRegT pMslRegBase,
                XLLP_INT32_T chan,
                XLLP_UINT8_T data)
{
    *((XLLP_UINT8_T*) &pMslRegBase->FifoReg.BBFIFO[chan]) = data;
}

__inline XLLP_UINT8_T XllpMslByteRead(
                P_XllpMslRegT pMslRegBase,
                XLLP_INT32_T chan)
{
    return (*((XLLP_UINT8_T*)&pMslRegBase->FifoReg.BBFIFO[chan]) & 0xFF);
}

__inline void XllpMslWordWrite(
                P_XllpMslRegT pMslRegBase,
                XLLP_INT32_T chan,
                XLLP_UINT32_T data
    )
{
    pMslRegBase->FifoReg.BBFIFO[chan] = data;
}

__inline XLLP_UINT32_T XllpMslWordRead(
                P_XllpMslRegT pMslRegBase,
                XLLP_INT32_T chan
    )
{
    return (pMslRegBase->FifoReg.BBFIFO[chan]);
}

#endif // _xllp_msl_h_
